home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 430_01 / m68kdis / inst1.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-29  |  12.1 KB  |  490 lines

  1. /*
  2.  *                 Author:  Christopher G. Phillips
  3.  *              Copyright (C) 1994 All Rights Reserved
  4.  *
  5.  *                              NOTICE
  6.  *
  7.  * Permission to use, copy, modify, and distribute this software and
  8.  * its documentation for any purpose and without fee is hereby granted
  9.  * provided that the above copyright notice appear in all copies and
  10.  * that both the copyright notice and this permission notice appear in
  11.  * supporting documentation.
  12.  *
  13.  * The author makes no representations about the suitability of this
  14.  * software for any purpose.  This software is provided ``as is''
  15.  * without express or implied warranty.
  16.  */
  17.  
  18. /*
  19.  * This file contains the functions called based on the high nibble
  20.  * of the potentially valid instruction word.  Most of these call
  21.  * functions in file inst2.c based on the remaining bits.
  22.  */
  23.  
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include "dis.h"
  27.  
  28. void
  29. bit_movep_immediate(m68kword inst)
  30. {
  31.     if (inst == 0x003c)
  32.         biti_reg("ORI", BYTE, "CCR");    /* 0000 0000 0011 1100 */
  33.     else if (inst == 0x007c)
  34.         biti_reg("ORI", WORD, "SR");    /* 0000 0000 0111 1100 */
  35.     else if ((inst & 0xff00) == 0x0600)
  36.         biti_size("ADDI", inst);    /* 0000 0110 ---- ---- */
  37.     else if ((inst & 0xf9c0) == 0x00c0) {
  38.         if (CPU(chip) >= MC68020)
  39.             cmp2_chk2(inst);    /* 0000 0--0 11-- ---- */
  40.     } else if ((inst & 0xff00) == 0)
  41.         biti_size("ORI", inst);        /* 0000 0000 ---- ---- */
  42.     else if (inst == 0x023c)
  43.         biti_reg("ANDI", BYTE, "CCR");    /* 0000 0010 0011 1100 */
  44.     else if (inst == 0x027c)
  45.         biti_reg("ANDI", WORD, "SR");    /* 0000 0010 0111 1100 */
  46.     else if ((inst & 0xff00) == 0x0200)
  47.         biti_size("ANDI", inst);    /* 0000 0010 ---- ---- */
  48.     else if ((inst & 0xff00) == 0x0400)
  49.         biti_size("SUBI", inst);    /* 0000 0100 ---- ---- */
  50.     else if ((inst & 0x0138) == 0x0108)
  51.         movep(inst);            /* 0000 ---1 --00 1--- */
  52.     else if (inst & 0x0100)
  53.         bit_dynamic(inst);        /* 0000 ---1 ---- ---- */
  54.     else if ((inst & 0xff00) == 0x0800)
  55.         bit_static(inst);        /* 0000 1000 ---- ---- */
  56.     else if ((inst & 0xfdff) == 0x0cfc) {
  57.         if (CPU(chip) >= MC68020)
  58.             cas2(inst);        /* 0000 11-0 1111 1100 */
  59.     } else if ((inst & 0xf9c0) == 0x08fc) {
  60.         if (CPU(chip) >= MC68020)
  61.             cas(inst);        /* 0000 1--0 11-- ---- */
  62.     } else if (inst == 0x0a3c)
  63.         biti_reg("EORI", BYTE, "CCR");    /* 0000 1010 0011 1100 */
  64.     else if (inst == 0x0a7c)
  65.         biti_reg("EORI", WORD, "SR");    /* 0000 1010 0111 1100 */
  66.     else if ((inst & 0xff00) == 0x0a00)
  67.         biti_size("EORI", inst);    /* 0000 1010 ---- ---- */
  68.     else if ((inst & 0xff00) == 0x0c00)
  69.         biti_size("CMPI", inst);    /* 0000 1100 ---- ---- */
  70.     else if ((inst & 0x0e00) == 0x0e00) {
  71.         if (CPU(chip) >= MC68010)
  72.             moves(inst);        /* 0000 1110 ---- ---- */
  73.     }
  74.         
  75. }
  76.  
  77. void
  78. movebyte(m68kword inst)
  79. {
  80.     move(inst, BYTE);            /* 0001 ---- ---- ---- */
  81. }
  82.  
  83. void
  84. movelong(m68kword inst)
  85. {
  86.     move(inst, LONGWORD);            /* 0010 ---- ---- ---- */
  87. }
  88.  
  89. void
  90. moveword(m68kword inst)
  91. {
  92.     move(inst, WORD);            /* 0011 ---- ---- ---- */
  93. }
  94.  
  95. void
  96. misc(m68kword inst)
  97. {
  98.     if (CPU(chip) >= MC68020 && (inst & 0x0140) == 0x0100
  99.       || CPU(chip) < MC68020 && (inst & 0x01c0) == 0x0180)
  100.         chk(inst);            /* 0100 ---1 ?0-- ---- */
  101.     else if ((inst & 0x0ff8) == 0x09c0) {
  102.         if (CPU(chip) >= MC68020)
  103.             ext(inst);    /* extb /* 0100 1001 1100 0--- */
  104.     } else if ((inst & 0x01c0) == 0x01c0)
  105.         lea(inst);            /* 0100 ---1 11-- ---- */
  106.     else
  107.         switch ((inst >> 8) & 0xf) {
  108.         case 0:
  109.             if ((inst & 0x00c0) == 0x00c0)
  110. /* 0100 0000 11-- ---- */    movereg(inst, "SR", FROM);
  111.             else
  112. /* 0100 0000 ---- ---- */    misc_size("NEGX", inst);
  113.             break;
  114.         case 2:
  115.             if ((inst & 0x00c0) == 0x00c0) {
  116.                 if (CPU(chip) >= MC68010)
  117. /* 0100 0010 11-- ---- */        movereg(inst, "CCR", FROM);
  118.             } else
  119. /* 0100 0010 ---- ---- */    misc_size("CLR", inst);
  120.             break;
  121.         case 4:
  122.             if ((inst & 0x00c0) == 0x00c0)
  123. /* 0100 0100 11-- ---- */    movereg(inst, "CCR", TO);
  124.             else
  125. /* 0100 0100 ---- ---- */    misc_size("NEG", inst);
  126.             break;
  127.         case 6:
  128.             if ((inst & 0x00c0) == 0x00c0)
  129. /* 0100 0110 11-- ---- */    movereg(inst, "SR", TO);
  130.             else
  131. /* 0100 0110 ---- ---- */    misc_size("NOT", inst);
  132.             break;
  133.         case 8:
  134.             if ((inst & 0x00f8) == 0x0008) {
  135. /* 0100 1000 0000 1--- */    link(inst, LONGWORD);
  136.                 flags |= ISLINK;
  137.             } else if ((inst & 0x00c0) == 0)
  138. /* 0100 1000 00-- ---- */    misc_ea("NBCD", inst, BYTE);
  139.             else if ((inst & 0x00f8) == 0x0040)
  140. /* 0100 1000 0100 0--- */    swap(inst);
  141.             else if ((inst & 0x00f8) == 0x0048) {
  142.                 if (CPU(chip) >= MC68010)
  143. /* 0100 1000 0100 1--- */        bkpt(inst);
  144.             } else if ((inst & 0x00c0) == 0x0040)
  145. /* 0100 1000 01-- ---- */    misc_ea("PEA", inst, LONGWORD);
  146.             else if ((inst & 0x00b8) == 0x0080)
  147. /* 0100 1000 1-00 0--- */    ext(inst);
  148.             else if ((inst & 0x0080) == 0x0080)
  149. /* 0100 1000 1--- ---- */    movem(inst, FROM);
  150.             break;
  151.         case 10:
  152.             if (inst == 0x4afc) {
  153. /* 0100 1010 1111 1100 */    instprint(ops2f(0), "ILLEGAL");
  154.                 valid = 1;
  155.             } else if ((inst & 0x00c0) == 0x00c0)
  156. /* 0100 1010 11-- ---- */    misc_ea("TAS", inst, BYTE);
  157.             else
  158. /* 0100 1010 ---- ---- */    misc_size("TST", inst);
  159.             break;
  160.         case 12:
  161.             if ((inst & 0x00c0) == 0) {
  162.                 if (CPU(chip) >= MC68020)
  163. /* 0100 1100 00-- ---- */        op2long("MUL", inst);
  164.             } else if ((inst & 0x00c0) == 0x0040) {
  165.                 if (CPU(chip) >= MC68020)
  166. /* 0100 1100 01-- ---- */        op2long("DIV", inst);
  167.             } else
  168. /* 0100 1100 1--- ---- */    movem(inst, TO);
  169.             break;
  170.         case 14:
  171.             switch ((inst >> 4) & 0xf) {
  172.             case 4:
  173. /* 0100 1110 0100 ---- */    trap(inst);
  174.                 break;
  175.             case 5:
  176.                 if (inst & 8) {
  177. /* 0100 1110 0101 1--- */        unlk(inst);
  178.                     flags |= ISUNLK;
  179.                 } else {
  180. /* 0100 1110 0101 0--- */        link(inst, WORD);
  181.                     flags |= ISLINK;
  182.                 }
  183.                 break;
  184.             case 6:
  185.                 if (inst & 8)
  186. /* 0100 1110 0110 1--- */        moveusp(inst, FROM);
  187.                 else
  188. /* 0100 1110 0110 0--- */        moveusp(inst, TO);
  189.                 break;
  190.             case 7:
  191.                 switch (inst & 0xf) {
  192.                 case 0:
  193. /* 0100 1110 0111 0000 */        instprint(ops2f(0), "RESET");
  194.                     valid = 1;
  195.                     break;
  196.                 case 1:
  197. /* 0100 1110 0111 0001 */        instprint(ops2f(0), "NOP");
  198.                     valid = 1;
  199.                     break;
  200.                 case 2:
  201. /* 0100 1110 0111 0010 */        stop_rtd("STOP");
  202.                     break;
  203.                 case 3:
  204. /* 0100 1110 0111 0011 */        instprint(ops2f(0), "RTE");
  205.                     flags |= ISRTS;
  206.                     valid = 1;
  207.                     break;
  208.                 case 4:
  209.                     if (CPU(chip) >= MC68010) {
  210. /* 0100 1110 0111 0100 */            stop_rtd("RTD");
  211.                         flags |= ISRTS;
  212.                         valid = 1;
  213.                     }
  214.                     break;
  215.                 case 5:
  216. /* 0100 1110 0111 0101 */        instprint(ops2f(0), "RTS");
  217.                     flags |= ISRTS;
  218.                     valid = 1;
  219.                     break;
  220.                 case 6:
  221. /* 0100 1110 0111 0110 */        instprint(ops2f(0), "TRAPV");
  222.                     valid = 1;
  223.                     break;
  224.                 case 7:
  225. /* 0100 1110 0111 0111 */        instprint(ops2f(0), "RTR");
  226.                     flags |= ISRTS;
  227.                     valid = 1;
  228.                     break;
  229.                 default:
  230.                     if ((inst & 0xe) == 0xa
  231.                       && CPU(chip) >= MC68010)
  232. /* 0100 1110 0111 101- */            movec(inst & 1);
  233.                     break;
  234.                 }
  235.                 break;
  236.             default:
  237.                 pcrelative = 1;
  238.                 if (inst & 0x0040) {
  239. /* 0100 1110 11-- ---- */        misc_ea("JMP", inst, 0);
  240.                     flags |= ISJMP;
  241.                 } else {
  242. /* 0100 1110 10-- ---- */        misc_ea("JSR", inst, 0);
  243.                     flags |= ISJSR;
  244.                 }
  245.                 pcrelative = 0;
  246.                 break;
  247.             }
  248.             break;
  249. #ifdef __alpha
  250.         /* Stupid DEC compiler */
  251.         case 15:
  252.             break;
  253. #endif
  254.         }
  255. }
  256.  
  257. void
  258. addq_subq_scc_dbcc_trapcc(m68kword inst)
  259. {
  260.     if ((inst & 0x00c0) == 0x00c0) {
  261.         if ((inst & 0x0038) == 0x0008) {
  262.             dbcc(inst);        /* 0101 ---- 1100 1--- */
  263.             flags |= ISDBcc;
  264.         } else if ((inst & 0x0038) == 0x0038
  265.           && 2 <= (inst & 7) && (inst & 7) <= 4) {
  266.             if (CPU(chip) >= MC68020)
  267.                 trapcc(inst);    /* 0101 ---- 1111 1--- */
  268.         } else
  269.             scc(inst);        /* 0101 ---- 11-- ---- */
  270.     } else
  271.         addq_subq(inst);        /* 0101 ---- ---- ---- */
  272. }
  273.  
  274. int
  275. bcc_bsr(m68kword inst)
  276. {
  277.     long        value;
  278.     int        condition = (inst >> 8) & 0xf;
  279.     char        *cp;
  280.     m68kaddr    savedpc;
  281.     int        failure = 0;
  282.  
  283.     savedpc = pc;
  284.     if ((value = signextend(inst & 0xff, 8)) == 0)
  285.         value = getval(WORD, &failure);
  286.     else if (CPU(chip) >= MC68020 && value == -1)
  287.         value = getval(LONGWORD, &failure);
  288.     if (failure)
  289.         return 0;
  290.     if (onepass != INCONSISTENT
  291.       && (value < 0 && -value > savedpc - initialpc
  292.       || value > 0 && value + savedpc > initialpc + maxoffset
  293.       || !odd && value & 1))
  294.         return 0;
  295.  
  296.     switch (condition) {
  297.     case 0:
  298.         cp = "RA";        /* 0110 0000 ---- ---- */
  299.         flags |= ISBRA;
  300.         break;
  301.     case 1:
  302.         cp = "SR";        /* 0110 0001 ---- ---- */
  303.         flags |= ISBSR;
  304.         break;
  305.     default:
  306.         cp = cc[condition];    /* 0110 ---- ---- ---- */
  307.         flags |= ISBRcc;
  308.         break;
  309.     }
  310.     sprintf(buf1, "B%s", cp);
  311.  
  312.     if (pass == FIRSTPASS && onepass != INCONSISTENT) {
  313.         required[flags & 3] = value + savedpc;
  314.         flags++;
  315.     } else if (pass == LASTPASS && value + savedpc >= initialpc
  316.       && value + savedpc <= initialpc + maxoffset
  317.       && insts[value + savedpc - initialpc].labelnum)
  318.         sprintf(buf2, "L%d",
  319.           insts[value + savedpc - initialpc].labelnum);
  320.     else /* if (pass == DEBUGPASS
  321.       || value + savedpc > initialpc + maxoffset) */
  322.         /* immsprintf(buf2, value); */
  323.         sprintf(buf2, "%lx", (long)(value + savedpc));
  324.     instprint(ops2f(1), buf1, buf2);
  325.  
  326.     return 1;
  327. }
  328.  
  329.  
  330. void
  331. moveq(m68kword inst)    /* 0111 ---0 ---- ---- */
  332. {
  333.     int    reg = (inst >> 9) & 7;
  334.     int    value;
  335.  
  336.     if (inst & 0x0100)
  337.         return;
  338.     value = signextend(inst & 0xff, 8);
  339.     sprintf(buf1, "%d", value);
  340.     sprintf(buf2, "D%d", reg);
  341.     instprint(ops2f(2) | sharp2f(1), "MOVEQ", buf1, buf2);
  342.  
  343.     valid = 1;
  344. }
  345.  
  346. void
  347. or_div_sbcd(m68kword inst)
  348. {
  349.     if ((inst & 0x01f0) == 0x0100)
  350.         opx("SBCD", inst, 4, 0);    /* 1000 ---1 0000 ---- */
  351.     else if ((inst & 0x01f0) == 0x0140)
  352.         pack_unpk("PACK", inst);    /* 1000 ---1 0100 ---- */
  353.     else if ((inst & 0x01f0) == 0x0180)
  354.         pack_unpk("UNPK", inst);    /* 1000 ---1 1000 ---- */
  355.     else if ((inst & 0x00c0) == 0x00c0)
  356.         op2("DIV", inst);        /* 1000 ---- 11-- ---- */
  357.     else
  358.         op1("OR", inst);        /* 1000 ---- ---- ---- */
  359. }
  360.  
  361. void
  362. sub_subx(m68kword inst)
  363. {
  364.     if ((inst & 0x00c0) == 0x00c0)
  365.         opa("SUBA", inst);        /* 1001 ---- 11-- ---- */
  366.     else if ((inst & 0x0130) == 0x0100)
  367.         opx("SUBX", inst, 4, 1);    /* 1001 ---1 --00 ---- */
  368.     else
  369.         op1("SUB", inst);        /* 1001 ---- ---- ---- */
  370. }
  371.  
  372. void
  373. unimplemented(m68kword inst)
  374. {
  375.     instprint(ops2f(0), "UNIMPLEMENTED");    /* 1010 ---- ---- ---- */
  376. }
  377.  
  378. void
  379. cmp_eor(m68kword inst)
  380. {
  381.     if ((inst & 0x00c0) == 0x00c0)
  382.         opa("CMPA", inst);        /* 1011 ---- 11-- ---- */
  383.     else if ((inst & 0x0100) == 0)
  384.         op1("CMP", inst);        /* 1011 ---0 ---- ---- */
  385.     else if ((inst & 0x0038) == 8)
  386.         opx("CMPM", inst, 3, 1);    /* 1011 ---1 --00 1--- */
  387.     else
  388.         op1("EOR", inst);        /* 1011 ---1 ---- ---- */
  389. }
  390.  
  391. void
  392. and_mul_abcd_exg(m68kword inst)
  393. {
  394.     if ((inst & 0x00c0) == 0x00c0)
  395.         op2("MUL", inst);        /* 1100 ---- 11-- ---- */
  396.     else if ((inst & 0x01f0) == 0x0100)
  397.         opx("ABCD", inst, 4, 0);    /* 1100 ---1 0000 ---- */
  398.     else
  399.         switch (inst & 0x01f8) {
  400.         case 0x0140:
  401.             exg(inst, 'D', 'D');    /* 1100 ---1 0100 0--- */
  402.             break;
  403.         case 0x0148:
  404.             exg(inst, 'A', 'A');    /* 1100 ---1 0100 1--- */
  405.             break;
  406.         case 0x0188:
  407.             exg(inst, 'D', 'A');    /* 1100 ---1 1000 1--- */
  408.             break;
  409.         default:
  410.             op1("AND", inst);    /* 1100 ---- ---- ---- */
  411.         }
  412. }
  413.  
  414. void
  415. add_addx(m68kword inst)
  416. {
  417.     if ((inst & 0x00c0) == 0x00c0)
  418.         opa("ADDA", inst);        /* 1101 ---- 11-- ---- */
  419.     else if ((inst & 0x0130) == 0x0100)
  420.         opx("ADDX", inst, 4, 1);    /* 1101 ---1 --00 ---- */
  421.     else
  422.         op1("ADD", inst);        /* 1101 ---- ---- ---- */
  423. }
  424.  
  425. void
  426. shift_rotate_bitfield(m68kword inst)
  427. {
  428.     if ((inst & 0x08c0) == 0x08c0) {
  429.         if (CPU(chip) >= MC68020)
  430.             bitfield(inst);        /* 1110 1--- 11-- ---- */
  431.     } else
  432.         shift(inst);            /* 1110 ---- ---- ---- */
  433. }
  434.  
  435. /*
  436.  * Coprocessor support.  Currently only the PMMU and FPU available.
  437.  */
  438.  
  439. struct cp    coproc[] = {
  440.     { "P",    pgen, pcc },
  441.     { "F",    fgen, fcc },
  442. };
  443. #define NCP    (sizeof coproc / sizeof coproc[0])
  444.  
  445. void
  446. coprocessor(m68kword inst)
  447. {
  448.     int        num = (inst >> 9) & 7;
  449.     struct cp    *cpptr;
  450.     const char    *prefix;
  451.  
  452.     if (num >= NCP || !coproc[num].prefix)
  453.         return;
  454.  
  455.     cpptr = &coproc[num];
  456.     prefix = cpptr->prefix;
  457.  
  458.     if (num == 0 && PMMU(chip) != MC68851
  459.       && (CPU(chip) < MC68030 || ((inst >> 6) & 7)))
  460.         return;
  461.     if (num == 1 && !FPU(chip))
  462.         return;
  463.     
  464.     switch ((inst >> 6) & 7) {
  465.     case 0:
  466.         (*cpptr->gen)(inst);    /* 1111 num0 00-- ---- */
  467.         if (valid && num == 1)
  468.             flags |= ISFPU;
  469.         break;
  470.     case 1:
  471.         if ((inst & 0x0038) == 0x0038)
  472.             cptrapcc(cpptr, inst);    /* 1111 num0 0111 1--- */
  473.         else if ((inst & 0x0038) == 0x0008)
  474.             cpdbcc(cpptr, inst);    /* 1111 num0 0100 1--- */
  475.         else
  476.             cpscc(cpptr, inst);    /* 1111 num0 01-- ---- */
  477.         break;
  478.     case 2:
  479.     case 3:
  480.         cpbcc(cpptr, inst);        /* 1111 num0 1--- ---- */
  481.         break;
  482.     case 4:
  483.         cpsave(prefix, inst);        /* 1111 num1 00-- ---- */
  484.         break;
  485.     case 5:
  486.         cprestore(prefix, inst);    /* 1111 num1 01-- ---- */
  487.         break;
  488.     }
  489. }
  490.